package com.office.util;

import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;

import javax.imageio.ImageIO;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 读取文件中的图片工具类*
 * @author tianyf
 */
public class ReadFileImageUtil {

    /**
     * 图片持久化地址*
     * 要手动初始化好，要么报错了*
     */
    private static String targetFolder = "C:\\testFile\\image\\";

    /**
     * 带 . 的图片后缀*
     */
    private static String suffix = ".jpg";

    /**
     * *
     */
    private static String postfix = "jpg";

    /**
     * 读取 pptx / ppt 的图片信息
     * * 传入一个 文件路径以及POI的读取文件内容的参数
     * * 返回一个存储路径名称集合*
     * @param pptxBytes
     */
    public static List<File> readPPTxPicture(byte[] pptxBytes) throws IOException {
        //初始化返回值
        List<File> listFile = new ArrayList<File>();
        //字节流读取
        InputStream pptxStream = new ByteArrayInputStream(pptxBytes);
        //初始化poi对ppt的读写操作
        XMLSlideShow xmlslideShow = new XMLSlideShow(pptxStream);
        //读取图片 集合信息
        List<XSLFPictureData> pictureData = xmlslideShow.getPictureData();
        //遍历图片信息
        for (XSLFPictureData pictureDatum : pictureData) {
            //初始化图片
            File file = new File(targetFolder + UUID.randomUUID() + suffix);
            //初始化流
            FileOutputStream out = new FileOutputStream(file);
            //写入
            out.write(pictureDatum.getData());
            //关流
            out.close();
            listFile.add(file);
        }
        //关流
        pptxStream.close();
        return listFile;
    }

    /**
     * 从word的doc里面提取图片
     * 仅支持 .doc 文件
     * @return
     * @param docBytes
     */
    public static List<File> readDocPicture(byte[] docBytes) throws IOException {
        //初始化返回值
        List<File> listFile = new ArrayList<File>();
        //byte数组转输入流
        InputStream docStream = new ByteArrayInputStream(docBytes);
        //初始化POI的读取 doc的document模板
        HWPFDocument hwpfDocument = new HWPFDocument(docStream);
        //读取所有table下的所有图片
        List<Picture> allPictures = hwpfDocument.getPicturesTable().getAllPictures();
        //循环所有图片信息 并保存至相关路径
        for (Picture pic : allPictures){
            File docFileImage = new File(targetFolder + UUID.randomUUID() + suffix);
            FileOutputStream fos = new FileOutputStream(docFileImage);
            fos.write(pic.getContent());
            fos.close();
            listFile.add(docFileImage);
        }
        docStream.close();
        return listFile;

    }

    /**
     * 从word的docx里面提取图片
     * 仅支持 .docx 使用*
     * @return
     * @param docxBytes
     */
    public static List<File> readDocxPicture(byte[] docxBytes) throws IOException {
        //初始化返回值信息
        List<File> fileList = new ArrayList<File>();
        //转成输入流
        InputStream docxStream = new ByteArrayInputStream(docxBytes);
        try {
            //用XWPFDocument来获取所有的图片
            XWPFDocument xwpfDocument = new XWPFDocument(docxStream);
            List<XWPFPictureData> picList = xwpfDocument.getAllPictures();
            for (XWPFPictureData pic : picList) {
                File docxFile = new File(targetFolder + UUID.randomUUID() + suffix);
                FileOutputStream fos = new FileOutputStream(docxFile);
                fos.write(pic.getData());
                fos.close();
                fileList.add(docxFile);
            }
            docxStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileList;
    }

    /**
     * 提取 pdf 图片
     * @param pdfBytes
     * @return
     * @throws IOException
     */
    public static List<File> readPdfPicture(byte[] pdfBytes){
        //初始化返回值
        List<File> listFile = new ArrayList<File>();
        try {
            //读取pdf的字节到 PDDocument 中
            PDDocument document = PDDocument.load(pdfBytes);
            //读取每页pdf的信息
            for (PDPage page : document.getPages()) {
                PDResources resources = page.getResources();
                for (COSName next : resources.getXObjectNames()) {
                    //如果 不是 文件类型的Xjob信息
                    if (!resources.isImageXObject(next)) {
                        continue;
                    }
                    //读取xjob并强转为image类型
                    PDImageXObject image = (PDImageXObject) resources.getXObject(next);
                    //初始化图片信息
                    File file = new File(targetFolder + UUID.randomUUID() + suffix);

                    //文件放入outPut流
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    ImageIO.write(image.getImage(), postfix, fileOutputStream);
                    fileOutputStream.close();
                    listFile.add(file);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return listFile;
    }

    /**
     * PDF提取图片方法*
     * 基于 pdfbox 1.8.13
     * 抛弃 : 原因是因为tika 1.21版本和pdf1.8.13版本内部jar包冲突*
     * 留下这个方法是为了避免出现类似问题*
     */
//    public static List<File> pdfPicture(File file) throws IOException {
//        List<File> listFile = new ArrayList<File>();
//        File newPdf = null;
//        if(file == null){
//            return null;
//        }
//        PDDocument document = PDDocument.load(file);
//        PDDocumentCatalog documentCatalog = document.getDocumentCatalog();
//
//        List allPages = documentCatalog.getAllPages();
//        Iterator<PDPage> iter = allPages.iterator();
//
//        int count = 0;
//        while(iter.hasNext()){
//            //获取到图片并判断非空
//            Map<String, PDXObjectImage> images = iter.next().getResources().getImages();
//            if(images != null){
//                Iterator<String> imageIter = images.keySet().iterator();
//                while(imageIter.hasNext()){
//                    //循环次数自增，来源是图片数量
//                    count++;
//                    // 拼接图片文件名
//                    newPdf = new File(targetFolder + "/" + UUID.randomUUID() + ".jpg");
//                    // 保存图片
//                    images.get(imageIter.next()).write2file(newPdf);
//
//                    listFile.add(newPdf);
//                }
//            }
//        }
//        return listFile;
//    }
}
